# -*- coding: utf-8 -*-
#urllib包用于向服务器发送get指令
from urllib.request import urlopen
#BeautifulSoup包用于解析html
from bs4 import BeautifulSoup
#pygal是绘制地图的工具，COUNTRIES是pygal中用于对应标准国家码的字典
from pygal_maps_world.i18n import COUNTRIES
import pygal_maps_world.maps
import pygal.style

#利用数组来存储解析后的信息
name = []
diagnosis = []
death = []

#向服务器发送指令
page = urlopen("https://www.bitpush.news/covid19/")
#转化为BeautifulSoup类
soup = BeautifulSoup(page)
#选择需要解析的元素，将数据信息存储于数组中
for i in soup.find_all(attrs={'class': 'table_card_cell_col_0 table_card_cell_stringwithicon_type'}):
    name.append(i.text)
for i in soup.find_all(attrs={'class': 'table_card_cell_col_1 table_card_cell_int_type'}):
    diagnosis.append(i.text)
for i in soup.find_all(attrs={'class': 'table_card_cell_col_4 table_card_cell_int_type'}):
    death.append(i.text)
#步骤1完成

#中-英字典字符串
country_list = "{'阿富汗': 'Afghanistan', '奥兰群岛': 'Aland Islands', '阿尔巴尼亚': 'Albania', '阿尔及利亚': 'Algeria', '美属萨摩亚': 'American Samoa', '安道尔': 'Andorra', '安哥拉': 'Angola', '安圭拉': 'Anguilla', '安提瓜和巴布达': 'Antigua and Barbuda', '阿根廷': 'Argentina', '亚美尼亚': 'Armenia', '阿鲁巴': 'Aruba', '澳大利亚': 'Australia', '奥地利': 'Austria', '阿塞拜疆': 'Azerbaijan', '孟加拉': 'Bangladesh', '巴林': 'Bahrain', '巴哈马': 'Bahamas', '巴巴多斯': 'Barbados', '白俄罗斯': 'Belarus', '比利时': 'Belgium', '伯利兹': 'Belize', '贝宁': 'Benin', '百慕大': 'Bermuda', '不丹': 'Bhutan', '玻利维亚': 'Bolivia', '波斯尼亚和黑塞哥维那': 'Bosnia and Herzegovina', '博茨瓦纳': 'Botswana', '布维岛': 'Bouvet Island', '巴西': 'Brazil', '文莱': 'Brunei', '保加利亚': 'Bulgaria', '布基纳法索': 'Burkina Faso', '布隆迪': 'Burundi', '柬埔寨': 'Cambodia', '喀麦隆': 'Cameroon', '加拿大': 'Canada', '佛得角': 'Cape Verde', '中非': 'Central African Republic', '乍得': 'Chad', '智利': 'Chile', '圣诞岛': 'Christmas Islands', '科科斯（基林）群岛': 'Cocos (keeling) Islands', '哥伦比亚': 'Colombia', '科摩罗': 'Comoros', '刚果（金）': 'Congo (Congo-Kinshasa)', '刚果': 'Congo', '库克群岛': 'Cook Islands', '哥斯达黎加': 'Costa Rica', '科特迪瓦': 'Cote D’Ivoire', '中国': 'China', '克罗地亚': 'Croatia', '古巴': 'Cuba', '捷克': 'Czech', '塞浦路斯': 'Cyprus', '丹麦': 'Denmark', '吉布提': 'Djibouti', '多米尼加': 'Dominica', '东帝汶': 'Timor-Leste', '厄瓜多尔': 'Ecuador', '埃及': 'Egypt', '赤道几内亚': 'Equatorial Guinea', '厄立特里亚': 'Eritrea', '爱沙尼亚': 'Estonia', '埃塞俄比亚': 'Ethiopia', '法罗群岛': 'Faroe Islands', '斐济': 'Fiji', '芬兰': 'Finland', '法国': 'France', '法国大都会': 'Franch Metropolitan', '法属圭亚那': 'Franch Guiana', '法属波利尼西亚': 'French Polynesia', '加蓬': 'Gabon', '冈比亚': 'Gambia', '格鲁吉亚': 'Georgia', '德国': 'Germany', '加纳': 'Ghana', '直布罗陀': 'Gibraltar', '希腊': 'Greece', '格林纳达': 'Grenada', '瓜德罗普岛': 'Guadeloupe', '关岛': 'Guam', '危地马拉': 'Guatemala', '根西岛': 'Guernsey', '几内亚比绍': 'Guinea-Bissau', '几内亚': 'Guinea', '圭亚那': 'Guyana', '香港 （中国）': 'Hong Kong', '海地': 'Haiti', '洪都拉斯': 'Honduras', '匈牙利': 'Hungary', '冰岛': 'Iceland', '印度': 'India', '印度尼西亚': 'Indonesia', '伊朗': 'Iran', '伊拉克': 'Iraq', '爱尔兰': 'Ireland', '马恩岛': 'Isle of Man', '以色列': 'Israel', '意大利': 'Italy', '牙买加': 'Jamaica', '日本': 'Japan', '泽西岛': 'Jersey', '约旦': 'Jordan', '哈萨克斯坦': 'Kazakhstan', '肯尼亚': 'Kenya', '基里巴斯': 'Kiribati', '韩国': 'Korea (South)', '朝鲜': 'Korea (North)', '科威特': 'Kuwait', '吉尔吉斯斯坦': 'Kyrgyzstan', '老挝': 'Laos', '拉脱维亚': 'Latvia', '黎巴嫩': 'Lebanon', '莱索托': 'Lesotho', '利比里亚': 'Liberia', '利比亚': 'Libya', '列支敦士登': 'Liechtenstein', '立陶宛': 'Lithuania', '卢森堡': 'Luxembourg', '澳门（中国）': 'Macau', '马其顿': 'Macedonia', '马拉维': 'Malawi', '马来西亚': 'Malaysia', '马达加斯加': 'Madagascar', '马尔代夫': 'Maldives', '马里': 'Mali', '马耳他': 'Malta', '马绍尔群岛': 'Marshall Islands', '马提尼克岛': 'Martinique', '毛里塔尼亚': 'Mauritania', '毛里求斯': 'Mauritius', '马约特': 'Mayotte', '墨西哥': 'Mexico', '密克罗尼西亚': 'Micronesia', '摩尔多瓦': 'Moldova', '摩纳哥': 'Monaco', '蒙古': 'Mongolia', '黑山': 'Montenegro', '蒙特塞拉特': 'Montserrat', '摩洛哥': 'Morocco', '莫桑比克': 'Mozambique', '缅甸': 'Myanmar', '纳米比亚': 'Namibia', '瑙鲁': 'Nauru', '尼泊尔': 'Nepal', '荷兰': 'Netherlands', '新喀里多尼亚': 'New Caledonia', '新西兰': 'New Zealand', '尼加拉瓜': 'Nicaragua', '尼日尔': 'Niger', '尼日利亚': 'Nigeria', '纽埃': 'Niue', '诺福克岛': 'Norfolk Island', '挪威': 'Norway', '阿曼': 'Oman', '巴基斯坦': 'Pakistan', '帕劳': 'Palau', '巴勒斯坦': 'Palestine', '巴拿马': 'Panama', '巴布亚新几内亚': 'Papua New Guinea', '巴拉圭': 'Paraguay', '秘鲁': 'Peru', '菲律宾': 'Philippines', '皮特凯恩群岛': 'Pitcairn Islands', '波兰': 'Poland', '葡萄牙': 'Portugal', '波多黎各': 'Puerto Rico', '卡塔尔': 'Qatar', '留尼汪岛': 'Reunion', '罗马尼亚': 'Romania', '卢旺达': 'Rwanda', '俄罗斯联邦': 'Russian Federation', '圣赫勒拿': 'Saint Helena', '圣基茨和尼维斯': 'Saint Kitts-Nevis', '圣卢西亚': 'Saint Lucia', '圣文森特和格林纳丁斯': 'Saint Vincent and the Grenadines', '萨尔瓦多': 'El Salvador', '萨摩亚': 'Samoa', '圣马力诺': 'San Marino', '圣多美和普林西比': 'Sao Tome and Principe', '沙特阿拉伯': 'Saudi Arabia', '塞内加尔': 'Senegal', '塞舌尔': 'Seychelles', '塞拉利昂': 'Sierra Leone', '新加坡': 'Singapore', '塞尔维亚': 'Serbia', '斯洛伐克': 'Slovakia', '斯洛文尼亚': 'Slovenia', '所罗门群岛': 'Solomon Islands', '索马里': 'Somalia', '南非': 'South Africa', '西班牙': 'Spain', '斯里兰卡': 'Sri Lanka', '苏丹': 'Sudan', '苏里南': 'Suriname', '斯威士兰': 'Swaziland', '瑞典': 'Sweden', '瑞士': 'Switzerland', '叙利亚': 'Syria', '塔吉克斯坦': 'Tajikistan', '坦桑尼亚': 'Tanzania', '台湾 （中国）': 'Taiwan', '泰国': 'Thailand', '特立尼达和多巴哥': 'Trinidad and Tobago', '多哥': 'Togo', '托克劳': 'Tokelau', '汤加': 'Tonga', '突尼斯': 'Tunisia', '土耳其': 'Turkey', '土库曼斯坦': 'Turkmenistan', '图瓦卢': 'Tuvalu', '乌干达': 'Uganda', '乌克兰': 'Ukraine', '阿拉伯联合酋长国': 'United Arab Emirates', '英国': 'United Kingdom', '美国': 'United States', '乌拉圭': 'Uruguay', '乌兹别克斯坦': 'Uzbekistan', '瓦努阿图': 'Vanuatu', '梵蒂冈': 'Vatican City', '委内瑞拉': 'Venezuela', '越南': 'Vietnam', '瓦利斯群岛和富图纳群岛': 'Wallis and Futuna', '西撒哈拉': 'Western Sahara', '也门': 'Yemen', '南斯拉夫': 'Yugoslavia', '赞比亚': 'Zambia', '津巴布韦': 'Zimbabwe'}"
#转化字符串为字典
country_dict = eval(country_list)
#存储转化后的字符串
UKname = []
namecode = []
#如果于字典相符则放入数组，否则放入原名
for i in name:
    #dict.keys(self)表示以数组存储字典的key值
    if i in country_dict.keys():
        #dict[key]可获取对应key值的value
        UKname.append(country_dict[i])
    else:
        UKname.append(i)
#由于COUNTRIES字典的key值为我们需要的值,无法直接对应，所以先写好查找函数用于替换
def get_country_code(country_name):
    #dict.items(self)中包含字典的全部对应关系
    #code遍历key，name遍历values
    for code,name in COUNTRIES.items():
        if name == country_name:
            #返回值即为key值
            return code
for i in UKname:
    if i in COUNTRIES.values():
        namecode.append(get_country_code(i))
    else:
        namecode.append(i)
#步骤2完成

#pygal提供了丰富的配色可供选择
map_style = pygal.style.RotateStyle('#336699')
#创建空地图模板
diagnosismap = pygal_maps_world.maps.World(style=map_style)
#deathmap = pygal_maps_world.maps.World()
diagnosismap.title = 'COVID-19 diagnosis'
#deathmap.title = 'COVID-19 death'
#将列表合并为字典，其中zip()用于将对象打包为元组，dict()将元组、数组转化为字典
diagnosis_dict = dict(zip(namecode,diagnosis))
#为处于不同感染人数量级的国家分配到不同的元组中
nums_codes1 = {}
nums_codes2 = {}
nums_codes3 = {}
nums_codes4 = {}
nums_codes5 = {}
#cc和pop分别遍历国家码与感染人数
for cc,pop in diagnosis_dict.items():
    #由于网站所提供的数据是千分位的字符串，所以先用replace方法将逗号去掉，以便int()进行强制类型转化
    pop = pop.replace(',','')
    #将第一行（表头标记）略去
    if pop == "确诊人数":
        continue
    #以数量级进行分类，并存于元祖中
    if int(pop) < 10000:
        nums_codes1[cc] = int(pop)
    elif int(pop) < 100000:
        nums_codes2[cc] = int(pop)
    elif int(pop) < 1000000:
        nums_codes3[cc] = int(pop)
    elif int(pop) < 10000000:
        nums_codes4[cc] = int(pop)
    else:
        nums_codes5[cc] = int(pop)
#把准备好的数据利用add方法添加到map中
diagnosismap.add('0-10000',nums_codes1)
diagnosismap.add('10000-100000',nums_codes2)
diagnosismap.add('100000-1000000',nums_codes3)
diagnosismap.add('1000000-10000000',nums_codes4)
diagnosismap.add('>10000000',nums_codes5)
#输出地图文件
diagnosismap.render_to_file('COVID-19 diagnosis.svg')
#步骤3结束